package class202205.demo10.demo09.sqlist;

import javax.xml.bind.annotation.XmlType;
import java.util.Arrays;

public class MyArraylist {
    //定义一个数组
    public int[] elem;
    //定义一个计数器
    public int usedSize;

    //也可以把数组长度写死
    private static final int DEFAULT_SIZE = 4;

    //提供一个MyArraylist的构造方法
    public MyArraylist() {
        //计数器不初始化默认为0，elem得初始化
        //this.elem = new int[4];
        this.elem = new int[DEFAULT_SIZE];
    }

    /**
     * curd-->增删改除操作
     */
    public void display() {
        /**
         * 打印顺序表
         * 跟据usedSize来判断即可
         */
        //此时的usedSize == 0,
        for (int i = 0; i < usedSize; i++) {
            System.out.print(this.elem[i] + " ");
        }
        System.out.println();
    }

    /**
     * 判断当前顺序表是否为满
     *
     * @return ture满  false代表空
     */
    public boolean isFull() {
        /*if (this.usedSize == this.elem.length){
            return true;
        }
        return false;*/
        //优化一下,它的返回值本来就是ture 或者 false
        return this.usedSize == this.elem.length;
    }

    // 新增元素,默认在数组最后新增
    public void add(int data) {
        //1、判断是否为满,如果满就扩容  拷贝一下，扩容谁呢（elem,2*elem.length） 扩容之后操作的是elem,所以指向新的对象elem
        if (this.isFull()) ;
        this.elem = Arrays.copyOf(this.elem, 2 * elem.length);

        //2、不满进行插入，如果满的，就进行扩容  在usedSize的地方添加data
        this.elem[this.usedSize] = data;
        this.usedSize++;//扩容后计数器++

    }

    /**
     * 添加方法
     * 也可以把pos位置判断定义为私有的  在add当中
     *
     * @param pos
     */
    private boolean checkPosInAdd(int pos) {
        if (pos < 0 || pos > usedSize) {
            System.out.println("pos位置不合法！");
            return true;//不合法
        }
        return false;//合法
    }

    // 在 pos 位置新增元素
    public void add(int pos, int data) {
        /*//判断pos位置
        if (pos<0 || pos>usedSize){
            System.out.println("pos位置不合法！");
            return;
        }*/
        //上面的pos判断  下标是否合法
        if (checkPosInAdd(pos)) {
            //return;//不合法就结束了    也可以抛一个异常----->  创建一个类 自定义一个异常
            throw new MyArrayListIndexOutOfException("添加方法的pos不合理！");
        }
        //判断顺序表是否为满
        if (isFull()) {
            this.elem = Arrays.copyOf(this.elem, 2 * elem.length);
        }
        //插入数据，  先往后挪（留出位置） 再插入
        for (int i = usedSize - 1; i >= pos; i--) {
            this.elem[i + 1] = this.elem[i];
        }
        //走到这里意味着挪完了  空出i=pos了   插入
        this.elem[pos] = data;
        this.usedSize++;
    }

    // 判定是否包含某个元素
    public boolean contains(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if (this.elem[i] == toFind) {
                return true;
            }
        }
        return false;
    }

    // 查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if (this.elem[i] == toFind) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 添加方法
     * 也可以把pos位置判断定义为私有的  在Get当中
     *
     * @param pos
     */
    private boolean checkPosInGet(int pos) {
        if (pos < 0 || pos >= usedSize) {
            System.out.println("pos位置不合法！");
            return true;//不合法
        }
        return false;//合法
    }

    // 获取 pos 位置的元素
    public int get(int pos) {
        /*//判断pos位置
        if (pos<0 || pos>usedSize){
            System.out.println("pos位置不合法！");
            return;
        }*/
        //上面的pos判断  下标是否合法   不用写判断空不空
        if (checkPosInAdd(pos)) {
            //return;//不合法就结束了    也可以抛一个异常----->  创建一个类 自定义一个异常
            throw new MyArrayListIndexOutOfException("获取pos下标是，位置不合法！");
        }
        //当然也可以判断一下空值问题  再写一个类  在下边判断
        if (isEmpty()) {
            throw new MyArrayListEmptyException("顺序表为空,不能删除！");
        }
        //pos合法了，返回pos下标
        return this.elem[pos];
    }

    /**
     * 关于上面的判别
     *
     * @return
     */
    public boolean isEmpty() {
        return usedSize == 0;
    }

    // 给 pos 位置的元素设为 value
    public void set(int pos, int value) {
        if (checkPosInGet(pos)) {
            throw new MyArrayListEmptyException("更新pos下标的元素，位置不合法！");
        }
        //如果合法，↓其实不用判断顺序表是否为空
        if (isEmpty()) {
            throw new MyArrayListEmptyException("顺序表为空！");
        }
        //顺序表为满的情况下也可以更新
        this.elem[pos] = value;
    }

    //删除第一次出现的关键字key
    public void remove(int key) {
        if (isEmpty()) {
            throw new MyArrayListEmptyException("顺序表为空！");
        }
        int index = indexOf(key);
        if (index == -1){
            System.out.println("不存在你要删除的数据！");
            return;
        }
        for (int i = index; i < usedSize-1; i++) {
            this.elem[i] = this.elem[i+1];
        }
        //循环退出，删除完成
        this.usedSize--;
        //this.elem[usedSize]=null;  //如果elem[usedSize]被引用  则需要置为空
    }

    // 获取顺序表长度
    public int size() {
        return usedSize;
    }

    // 清空顺序表
    public void clear() {
        /*
        如果是引用数据类型，一个一个置为空
        for (int i = 0; i < usedSize; i++) {
            this.elem[i] = null;
        }*/
        usedSize = 0;
    }
}
